package com.clippick;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import co.kr.clippick.R;

import com.clippick.api.GetApi;
import com.clippick.common.GlobalValue;
import com.clippick.common.Toasts;
import com.clippick.common.Utils;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.BaseRequestListener;
import com.facebook.android.FBUtils;
import com.facebook.android.Facebook;
import com.facebook.android.LoginButton;
import com.facebook.android.SessionEvents;
import com.facebook.android.SessionEvents.AuthListener;

public class NewLoginActivity extends Activity {
	private Context mContext;
	private ConnectivityManager manager;

	private LinearLayout backButtonLayer;
	private Button loginButton;
	private Button forgotButton;
	private Button facebookButton;
	private EditText emailEditText, passwordEditText;
	private LinearLayout forgotButtonLayer;
	private ProgressDialog mProgress = null;

	private String userEmail = "";
	private String userPassword = "";

	// facebook information
	private String[] permissions = { "publish_stream", "user_photos", "email" };
	private final static int AUTHORIZE_ACTIVITY_RESULT_CODE = 0;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.new_login);
		mContext = this;

		backButtonLayer = (LinearLayout) findViewById(R.id.back_button_layer);
		backButtonLayer.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});

		manager = (ConnectivityManager) mContext
				.getSystemService(Context.CONNECTIVITY_SERVICE);

		emailEditText = (EditText) findViewById(R.id.email);
		passwordEditText = (EditText) findViewById(R.id.password);
		passwordEditText
				.setOnEditorActionListener(new TextView.OnEditorActionListener() {
					@Override
					public boolean onEditorAction(TextView v, int actionId,
							KeyEvent event) {
						// TODO Auto-generated method stub
						if (actionId == EditorInfo.IME_ACTION_GO) {
							userEmail = emailEditText.getText().toString();
							userPassword = passwordEditText.getText()
									.toString();
							if (!userEmail.equals("")
									&& !userPassword.equals("")) {
								if (Utils.checkNetwokState(manager)) {
									new LoginTask().execute();
								} else {
									Toasts.showToast(mContext,
											getString(R.string.network_fail));
								}
							}
						}

						return true;
					}
				});

		loginButton = (Button) findViewById(R.id.login);
		loginButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				userEmail = emailEditText.getText().toString();
				userPassword = passwordEditText.getText().toString();
				if (!userEmail.equals("") && !userPassword.equals("")) {
					if (Utils.checkNetwokState(manager)) {
						new LoginTask().execute();
					} else {
						Toasts.showToast(mContext,
								getString(R.string.network_fail));
					}
				}
			}
		});

		forgotButton = (Button) findViewById(R.id.forgot);
		forgotButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(mContext, NewForgotActivity.class);
				startActivity(intent);
			}
		});

		forgotButtonLayer = (LinearLayout) findViewById(R.id.forgot_layer);
		forgotButtonLayer.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(mContext, NewForgotActivity.class);
				startActivity(intent);
			}
		});

		facebookButton = (Button) findViewById(R.id.facebook);
		facebookButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				loginWithFacebook();
			}
		});

		mProgress = new ProgressDialog(mContext);
		mProgress.setMessage("Loading...");

		// coming from NewJoinActivity.FacebookButton
		if (getIntent() != null) {
			if (getIntent().getExtras() != null) {
				if (getIntent().getBooleanExtra("facebook", false)) {
					loginWithFacebook();
				}
			}
		}
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case AUTHORIZE_ACTIVITY_RESULT_CODE:
			FBUtils.mFacebook.authorizeCallback(requestCode, resultCode, data);
			mProgress.show();
			break;
		}
	}

	private void loginWithFacebook() {
		FBUtils.mFacebook = new Facebook(getString(R.string.fb_app_id));
		FBUtils.mAsyncRunner = new AsyncFacebookRunner(FBUtils.mFacebook);
		SessionEvents.addAuthListener(new FbAPIsAuthListener());

		// restore session if one exists
		// boolean isFbUser = SessionStore.restore(FBUtils.mFacebook, mContext);
		if (!FBUtils.mFacebook.isSessionValid()) {
			LoginButton loginFB = new LoginButton(this);
			loginFB.init(this, AUTHORIZE_ACTIVITY_RESULT_CODE,
					FBUtils.mFacebook, permissions);
		} else {
			mProgress.show();
			new FacebookLoginTask().execute();
		}
	}

	// HTTP Request from thread
	class FacebookLoginTask extends AsyncTask<String, String, String> {
		String returnMessage = null;

		@Override
		protected String doInBackground(String... params) {
			GetApi api = new GetApi(mContext);
			returnMessage = api.loginWithFacebook(
					GlobalValue.getFacebookUUID(mContext),
					GlobalValue.getFacebookEmail(mContext));

			return null;
		}

		protected void onPostExecute(String unused) {
			mProgress.dismiss();
			try {
				JSONObject json = new JSONObject(returnMessage);
				int returnCode = Integer.parseInt(json.getString("returnCode"));
				Log.i("login", returnMessage);

				switch (returnCode) {
				case 200:
					GlobalValue.USER_ID = GlobalValue
							.getFacebookEmail(mContext);

					GlobalValue.storeUserRegistrationKey(mContext,
							json.getString("REGISTRATION_KEY"));
					GlobalValue.storeUserEmail(mContext, GlobalValue.USER_ID);
					GlobalValue.setMaxStarValue(mContext,
							Integer.parseInt(json.getString("MaxStar")));
					GlobalValue.setStarCountValue(mContext,
							Integer.parseInt(json.getString("UsedStar")));

					GlobalValue.setFbUser(mContext, true);
					GlobalValue.setAutoSync(mContext, true);
					GlobalValue.USER_KEY = json.getString("REGISTRATION_KEY");
					GlobalValue.AppLatestSyncTime = GlobalValue.UPDATE_TIME;
					GlobalValue.IS_FIRST_LOGIN_USER = true;

					Intent intent = new Intent(mContext, NewMainActivity.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
					startActivity(intent);

					Intent updateViewIntent = new Intent();
					updateViewIntent.setAction("com.new.clippick.FinishIntro");
					sendBroadcast(updateViewIntent);

					finish();
					break;

				default:
					break;
				}

			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

	private void hideKeyboard(EditText editText) {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
	}

	class LoginTask extends AsyncTask<String, String, String> {
		int returnCode = 0;
		String returnMessage = null;
		Map<String, String> response = null;

		protected void onPreExecute() {
			mProgress = new ProgressDialog(mContext);
			mProgress.setMessage("Loading");
			mProgress.setCancelable(false);
			mProgress.show();

			hideKeyboard(emailEditText);
			hideKeyboard(passwordEditText);
		}

		@Override
		protected String doInBackground(String... params) {
			GetApi api = new GetApi(mContext);
			response = api.loginApi(userEmail, userPassword);
			Log.i("login", response.toString());
			returnCode = Integer.parseInt(response.get("returnCode"));

			if (returnCode != 200) {
				returnMessage = response.get("returnMessage");
			}

			return null;
		}

		protected void onPostExecute(String unused) {
			mProgress.dismiss();

			switch (returnCode) {
			case 200:
				// store user data
				GlobalValue.storeUserEmail(mContext, userEmail);
				GlobalValue.storeUserPassword(mContext, userPassword);
				GlobalValue.storeUserRegistrationKey(mContext,
						response.get("REGISTRATION_KEY").toString());
				GlobalValue.setMaxStarValue(mContext,
						Integer.parseInt(response.get("MaxStar").toString()));
				GlobalValue.setStarCountValue(mContext,
						Integer.parseInt(response.get("UsedStar").toString()));
				GlobalValue.setFbUser(mContext, true);
				GlobalValue.setAutoSync(mContext, true);
				GlobalValue.USER_KEY = response.get("REGISTRATION_KEY")
						.toString();
				GlobalValue.AppLatestSyncTime = GlobalValue.UPDATE_TIME;
				GlobalValue.IS_FIRST_LOGIN_USER = true;

				// store as global variable to access easier
				GlobalValue.USER_ID = userEmail;
				GlobalValue.USER_KEY = GlobalValue
						.getUserRegistrationKey(mContext);
				GlobalValue.UPDATE_TIME = response.get("UPDATE_TIME")
						.toString();
				GlobalValue.AppLatestSyncTime = GlobalValue.UPDATE_TIME;
				GlobalValue.IS_FIRST_LOGIN_USER = true;

				Intent intent = new Intent(mContext, NewMainActivity.class);
				intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				startActivity(intent);

				Intent updateViewIntent = new Intent();
				updateViewIntent.setAction("com.new.clippick.FinishIntro");
				sendBroadcast(updateViewIntent);

				finish();

				break;

			default:
				// show message why failed logging in
				Toasts.showToast(mContext, returnMessage);
				break;
			}
		}
	}

	public class FbAPIsAuthListener implements AuthListener {
		public void onAuthSucceed() {
			Bundle params = new Bundle();
			params.putString("fields", "name, picture, email");
			FBUtils.mAsyncRunner.request("me", params,
					new UserRequestListener());
		}

		public void onAuthFail(String error) {
			Toasts.showToast(mContext, error);
			mProgress.dismiss();
		}
	}

	/*
	 * Callback for fetching current user's name, picture, uid.
	 */
	public class UserRequestListener extends BaseRequestListener {
		public void onComplete(final String response, final Object state) {
			JSONObject jsonObject;
			try {
				jsonObject = new JSONObject(response);

				// final String picURL = jsonObject.getString("picture");
				// final String name = jsonObject.getString("name");
				FBUtils.userUID = jsonObject.getString("id");
				GlobalValue.storeFacebookUUID(mContext, FBUtils.userUID);
				GlobalValue.storeFacebookEmail(mContext,
						jsonObject.getString("email"));

				new FacebookLoginTask().execute();

				try {
					Bundle parameters = new Bundle();
					parameters.putString("fields",
							"name, picture, email, age_range, gender");
					String info = FBUtils.mFacebook.request("me", parameters);
					Log.i("facebook", info);
				} catch (Exception e) {
					e.printStackTrace();
				}

			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}
}
